#include <server.h>
#include <common.h>
#include <stdlib.h>
#include <time.h>
#include <mqtt_client.h>
#include <pthread.h>
#include <sys/time.h>
#include <tpunb.h>
#include <system.h>
#include <devnode.h>
#include <recordModule.h>
#include <firmware.h>
#include <http_download.h>

#define ARRAYSIZE(a)	(sizeof(a) / sizeof(a[0]))

void gw_publish_setting_rsp_data(char *msg, int msglen)
{
	char topic[128] = {0};

	if(mqtt_client_connect_ok()) {
		DEBUG("setting_rsp:%s", msg);
		sprintf(topic, "/%s/respond/setting", get_gw_sn());
		mqtt_client_publish_data(topic, (unsigned char *)msg, msglen);
	}
}

void gw_publish_notify_req_data(char *msg, int msglen)
{
	char topic[128] = {0};
	
	if(mqtt_client_connect_ok()) {
		sprintf(topic, "/%s/request/notify", get_gw_sn());
		DEBUG("%d,%s:%s", msglen, topic, msg);
		mqtt_client_publish_data(topic, (unsigned char *)msg, msglen);
	}
}

void gw_platform_warnbox_json_up(char *msg, int msglen)
{
	char topic[128] = {0};
	
	if(mqtt_client_connect_ok()) {
		sprintf(topic, "/platform/warnbox/json/up");
		DEBUG("%d,%s:%s", msglen, topic, msg);
		mqtt_client_publish_data(topic, (unsigned char *)msg, msglen);
	}
}

//通过MQTT主题判断是否终端发过来的消息
static int is_terminal_message(char *topic)
{
	char topic_1[128] = {0};

	sprintf(topic_1, "/%s/terminal/up", get_terminal_gwsn());
	if(strcmp(topic_1, topic) == 0) {
		return 1;
	}

	return 0;
}

//广播报警器MQTT消息
void gw_publish_broadcast_terminal_message(unsigned char *msg, int msglen)
{
	char topic[128] = {0};
	char msg_str[512] = {0};

	if(msglen < 50) {
		hex2string(msg_str, msg, msglen);
	} else {
		hex2string(msg_str, msg, FRAME_PADDING_LEN);
	}
	
	if(mqtt_client_connect_ok()) {
		sprintf(topic, "/%s/terminal/down", get_terminal_gwsn());
		DEBUG("%d,%s:%s", msglen, topic, msg_str);
		mqtt_client_publish_data(topic, msg, msglen);
	}
}

//点播报警器MQTT消息
void gw_publish_terminal_message(char *terminal_devsn, unsigned char *msg, int msglen)
{
	char topic[128] = {0};
	char msg_str[512] = {0};

	if(msglen < 50) {
		hex2string(msg_str, msg, msglen);
	} else {
		hex2string(msg_str, msg, FRAME_PADDING_LEN);
	}
	
	if(mqtt_client_connect_ok()) {
		sprintf(topic, "/%s/%s/terminal/down", get_terminal_gwsn(), terminal_devsn);
		DEBUG("%d,%s:%s", msglen, topic, msg_str);
		mqtt_client_publish_data(topic, msg, msglen);
	}
}

static void setting_rsp(char *command, int ret)
{
	char *out;
	cJSON *root;
	root = cJSON_CreateObject();
	cJSON_AddNumberToObject(root, "id", generate_msgid());
	cJSON_AddStringToObject(root, "gwid", get_gw_sn());
	cJSON_AddStringToObject(root, "command", command);
	cJSON_AddNumberToObject(root, "ret", ret);
	out = cJSON_PrintUnformatted(root);
	cJSON_Delete(root);
	gw_publish_setting_rsp_data(out, strlen(out));
	free(out);
}

static void add_modify_dev_info(CLOUD_DATA *cloud_data)
{
	//本地json文件
	cJSON *root;
	int add_modify_count = 0;
	int found;

	int i,j;
	cJSON *devSn = NULL;
	//cJSON *devName = NULL;
	cJSON *devUser = NULL;
	//cJSON *devUserTel = NULL;
	cJSON *array = NULL;
	cJSON *element = NULL;
	int count = 0;

	cJSON *devSn_new = NULL;
	cJSON *devName_new = NULL;
	cJSON *devUser_new = NULL;
	cJSON *devUserTel_new = NULL;
	cJSON *array_new = NULL;
	cJSON *element_new = NULL;
	int count_new;

	cJSON *mode;

	DEV_NODE *dev_node;

	root = parse_root_from_file(DEV_NODE_FILE);
	if(root == NULL) {
		root = cJSON_CreateObject();
		cJSON_AddItemToObject(root, "data", cJSON_CreateArray());
	} else {
		mode = cJSON_GetObjectItem(root, "mode");
		if(mode) {
			if(mode->type == cJSON_String && strcmp(mode->valuestring, "test") == 0) {
				free_root(root);
				root = cJSON_CreateObject();
				cJSON_AddItemToObject(root, "data", cJSON_CreateArray());
			}
		}
	}

	//平台数据数组
	array_new = cJSON_GetObjectItem(cloud_data->root, "data");
	count_new = cJSON_GetArraySize(array_new);

	//本地数据数组
	array = cJSON_GetObjectItem(root, "data");

	if(array)
		count = cJSON_GetArraySize(array);

	for(j=0;j<count_new;j++) {
		element_new = cJSON_GetArrayItem(array_new, j);
		if(element_new) {
			devSn_new = cJSON_GetObjectItem(element_new, "devSn");
			devName_new = cJSON_GetObjectItem(element_new, "devName");
			devUser_new = cJSON_GetObjectItem(element_new, "devUser");
			devUserTel_new = cJSON_GetObjectItem(element_new, "devUserTel");
		}

		if(devSn_new && devName_new && devUser_new && devUserTel_new) {
			found = 0;
			
			for(i=0; i<count; i++) {
				element = cJSON_GetArrayItem(array, i);
				devSn = cJSON_GetObjectItem(element, "devSn");
				devUser = cJSON_GetObjectItem(element, "devUser");

				if(strcmp(devSn->valuestring, devSn_new->valuestring) == 0 || 
					strcmp(devUser->valuestring, devUser_new->valuestring) == 0) {
					//修改
					DEBUG("modify dev info :%s", devSn_new->valuestring);
					cJSON_DetachItemFromArray(array_new, j);--j;--count_new;
					cJSON_ReplaceItemInArray(array, i, element_new);

					//以上两句代码替换下面四句代码
					//cJSON_ReplaceItemInObject(element, "devSn", devSn_new);
					//cJSON_ReplaceItemInObject(element, "devName", devName_new);
					//cJSON_ReplaceItemInObject(element, "devUser", devUser_new);
					//cJSON_ReplaceItemInObject(element, "devUserTel", devUserTel_new);
					++add_modify_count;
					found = 1;
					break;
				}
			}

			if(found == 0) {
				//添加
				DEBUG("add dev info :%s", devSn_new->valuestring);
				cJSON_DetachItemFromArray(array_new, j);--j;--count_new;
				cJSON_AddItemToArray(array, element_new);
				++add_modify_count;
			}

			dev_node = get_dev_node(devSn_new->valuestring);
			if((dev_node == NULL) || (dev_node && dev_node->online == 0))
				oline_unicast_of_devSn(devSn_new->valuestring);//点播是否在线
		}
	}

	if(add_modify_count > 0) {
		//保存文件
		save_root_to_file(root, DEV_NODE_FILE);
		//更新设备列表
		update_devnode_from_file(DEV_NODE_FILE);
		//通知qt页面更新
		update_devnode_notify_qt();
	}

	//反馈平台
	setting_rsp(cloud_data->command, add_modify_count);

	//释放内存
	free_root(root);
}

static void del_dev_info(CLOUD_DATA *cloud_data)
{
	//本地json文件
	cJSON *root;
	int del_count = 0;

	int i,j;
	cJSON *devSn = NULL;
	cJSON *array = NULL;
	cJSON *element = NULL;
	int count = 0;

	cJSON *devSn_del = NULL;
	cJSON *array_del = NULL;
	cJSON *element_del = NULL;
	int count_del = 0;

	root = parse_root_from_file(DEV_NODE_FILE);
	if(root == NULL) {
		return;
	}

	//平台数据数组
	array_del = cJSON_GetObjectItem(cloud_data->root, "data");
	if(array_del)
		count_del = cJSON_GetArraySize(array_del);

	//本地数据数组
	array = cJSON_GetObjectItem(root, "data");
	if(array)
		count = cJSON_GetArraySize(array);

	for(j=0; j<count_del; j++) {
		element_del = cJSON_GetArrayItem(array_del, j);
		if(element_del) {
			devSn_del = cJSON_GetObjectItem(element_del, "devSn");
		}

		if(devSn_del) {
			for(i=0; i<count; i++) {
				element = cJSON_GetArrayItem(array, i);
				devSn = cJSON_GetObjectItem(element, "devSn");

				if(strcmp(devSn->valuestring, devSn_del->valuestring) == 0) {
					//修改
					DEBUG("del dev info :%s", devSn_del->valuestring);
					cJSON_DeleteItemFromArray(array, i);--i;--count;
					++del_count;
					break;
				}
			}
		}
	}

	if(del_count > 0) {
		//保存文件
		save_root_to_file(root, DEV_NODE_FILE);
		//更新设备列表
		update_devnode_from_file(DEV_NODE_FILE);
		//通知qt页面更新
		update_devnode_notify_qt();
	}

	//反馈平台
	setting_rsp(cloud_data->command, del_count);

	//释放内存
	free_root(root);
}


static void clear_dev_info(CLOUD_DATA *cloud_data)
{
	cJSON *root;
	root = cJSON_CreateObject();
	cJSON_AddItemToObject(root, "data", cJSON_CreateArray());
	save_root_to_file(root, DEV_NODE_FILE);	
	free_root(root);
	
	setting_rsp(cloud_data->command, 0);
	update_devnode_from_file(DEV_NODE_FILE);
	update_devnode_notify_qt();
}

static void get_dev_info(CLOUD_DATA *cloud_data)
{
	char *out;
	cJSON *root;
	cJSON *devinfo;
	cJSON *data;

	root = cJSON_CreateObject();
	cJSON_AddNumberToObject(root, "id", generate_msgid());
	cJSON_AddStringToObject(root, "gwid", get_gw_sn());
	cJSON_AddStringToObject(root, "command", cloud_data->command);

	devinfo = parse_root_from_file(DEV_NODE_FILE);
	if(devinfo) {
		data = cJSON_DetachItemFromObject(devinfo, "data");
		if(data)
			cJSON_AddItemToObject(root, "data", data);
		cJSON_Delete(devinfo);
	}

	out = cJSON_PrintUnformatted(root);
	cJSON_Delete(root);
	gw_publish_setting_rsp_data(out, strlen(out));
	free(out);
}

static void gw_heartbeat_rsp(CLOUD_DATA *cloud_data)
{
	DEBUG("heartbeat rsp %s", cloud_data->gwid);
}

static void gw_setNetinfo_req(CLOUD_DATA *cloud_data)
{
	int ret = -1;
	cJSON *gwAddr;
	cJSON *cellid;
	cJSON *group;
	cJSON *terminalgwid;

	gwAddr = cJSON_GetObjectItem(cloud_data->root, "gwAddr");				//"65535"或65535或"FFFF"
	cellid = cJSON_GetObjectItem(cloud_data->root, "gwCellid");
	group = cJSON_GetObjectItem(cloud_data->root, "gwGroup");
	if(gwAddr && cellid && group) {
		if(gwAddr->type == cJSON_String) {
			gwAddr->valueint = strtoul(gwAddr->valuestring, NULL, 10);		//十进制解析
			
			if(gwAddr->valueint == 0)
				gwAddr->valueint = strtoul(gwAddr->valuestring, NULL, 16);	//十六进制解析
		}

		if(cellid->type == cJSON_String) {
			cellid->valueint = strtoul(cellid->valuestring, NULL, 10);
		}

		ret = netInfo_settings(gwAddr->valueint, cellid->valueint, group->valueint);
	}

	terminalgwid = cJSON_GetObjectItem(cloud_data->root, "terminalgwid");
	if(terminalgwid) {
		set_terminal_gwsn(terminalgwid->valuestring);
		mqtt_client_reconnect();
	}

	if(ret < 0)
		gw_netInfo_settings_rsp();
}

static void gw_setdevNodeNetinfo_req(CLOUD_DATA *cloud_data)
{
	cJSON *devid;
	cJSON *cellid;
	cJSON *nodeAddr;
	cJSON *gwaddr;
	int ret = -1;
	int gw_Addr = 0;
	int node_Addr = -1;

	devid = cJSON_GetObjectItem(cloud_data->data, "devSn");
	nodeAddr = cJSON_GetObjectItem(cloud_data->data, "addr");			//"65535"或65535或"FFFF"
	cellid = cJSON_GetObjectItem(cloud_data->data, "cellid");
	gwaddr = cJSON_GetObjectItem(cloud_data->data, "gwAddr");
	if(devid && node_Addr && gwaddr && cellid) {
		if(gwaddr->type == cJSON_Number) {
			gw_Addr = gwaddr->valueint;
		} else if(gwaddr->type == cJSON_String) {
			gw_Addr = strtoul(gwaddr->valuestring, NULL, 10);
		}

		if(nodeAddr->type == cJSON_Number) {
			node_Addr = nodeAddr->valueint;
		} else if(nodeAddr->type == cJSON_String) {
			node_Addr = strtoul(nodeAddr->valuestring, NULL, 10);
			
			if(node_Addr == 0)
				node_Addr = strtoul(nodeAddr->valuestring, NULL, 16);
		}
	
		ret = set_dev_node_netinfo(gw_Addr, devid->valuestring, node_Addr, cellid->valueint);
	}

	if(ret < 0) {
		setting_rsp(cloud_data->command, ret);
	}
}

static void gw_tpunbTransparent_req(CLOUD_DATA *cloud_data)
{
	int command = 0;
	int len = 0;
	unsigned char command_data[1024] = {0};

	cJSON *cmdType;
	cJSON *hexData;
	cJSON *addr;

	hydrology_param_t hydrology_param;

	cmdType = cJSON_GetObjectItem(cloud_data->root, "cmdType");
	hexData = cJSON_GetObjectItem(cloud_data->root, "hexData");
	addr = cJSON_GetObjectItem(cloud_data->root, "addr");

	memset(&hydrology_param, 0, sizeof(hydrology_param));
	if(addr) {
		hydrology_param.addr = strtoul(addr->valuestring, NULL, 16);	//点播
	} else {
		hydrology_param.addr = 0;	//广播
	}

	if(cmdType) {
		if(hexData) {
			command = strtoul(cmdType->valuestring, NULL, 16);
			len = string2hex(command_data, hexData->valuestring);
			hydrology_param.cmdtype = command;
			hydrology_param.buf = command_data;
			hydrology_param.length = len;
			hydrology_transform_enqueue(&hydrology_param);
		} else {
			command = strtoul(cmdType->valuestring, NULL, 16);
			hydrology_param.cmdtype = command;
			hydrology_param.buf = NULL;
			hydrology_param.length = 0;
			hydrology_transform_enqueue(&hydrology_param);
		}
	}
}

static void gw_waterLevel_req(CLOUD_DATA *cloud_data)
{
	save_root_to_file(cloud_data->root, WATER_LEVEL_FILE);
	water_alarm_info_parse(WATER_LEVEL_FILE);
	setting_rsp(cloud_data->command, 0);
}

static void gw_warnNotify_req(CLOUD_DATA *cloud_data)
{	
	cJSON *warn_level;
    int alarm_level = 0;

	warn_level = cJSON_GetObjectItem(cloud_data->data, "warn_level");
	if(warn_level) {
		alarm_level = warn_level->valueint;
		if (alarm_level >= 1 && alarm_level <= 3) {
			//弹出qt注意安全界面
			//trigger_alarm_notify_qt(alarm_level);

			//停止播报
			stop_voice_broadcast();

			//播报注意安全语音
			start_voice_broadcast(alarm_level, 0);
		} else if(alarm_level == 0) {
			//上报0,非报警值
			trigger_alarm_notify_qt(0);

			//停止播报
			stop_voice_broadcast();
		}

		setting_rsp(cloud_data->command, 0);
	}
}

static void firmware_upgrade_req(CLOUD_DATA *cloud_data)
{
	cloud_firmware_upgrade_req(cloud_data);
}

static void online_scan_req(CLOUD_DATA *cloud_data)
{
	cJSON *dev_sn = NULL;

	if(cloud_data->data) {
		dev_sn = cJSON_GetObjectItem(cloud_data->data, "devSn");
	}

	if(cloud_data->data == NULL || dev_sn == NULL) {
		dev_online_scan(NULL);
	} else {
		dev_online_scan(dev_sn->valuestring);
	}

	setting_rsp(cloud_data->command, 0);
}

static void warn_notify_req(CLOUD_DATA *cloud_data)
{
	cJSON *dev_sn = NULL;
	cJSON *warn_level = NULL;

	if(cloud_data->data) {
		dev_sn = cJSON_GetObjectItem(cloud_data->data, "devSn");
	}

	if(cloud_data->data == NULL) {
		setting_rsp(cloud_data->command, -1);
		return;
	}

	dev_sn = cJSON_GetObjectItem(cloud_data->data, "devSn");
	warn_level = cJSON_GetObjectItem(cloud_data->data, "warn_level");

	if(warn_level != NULL) {
		if(dev_sn == NULL) {
			dev_warn_notify(NULL, warn_level->valueint);
		} else {
			dev_warn_notify(dev_sn->valuestring, warn_level->valueint);
		}

		setting_rsp(cloud_data->command, 0);
	} else {
		setting_rsp(cloud_data->command, -2);
	}
}

static void warn_cancel_req(CLOUD_DATA *cloud_data)
{
	cJSON *dev_sn = NULL;

	if(cloud_data->data) {
		dev_sn = cJSON_GetObjectItem(cloud_data->data, "devSn");
	}

	if(cloud_data->data == NULL || dev_sn == NULL) {
		dev_warn_cancel_notify(NULL);
	} else {
		dev_warn_cancel_notify(dev_sn->valuestring);
	}

	setting_rsp(cloud_data->command, 0);
}

static void update_broadcast_task_4(char *filepath)
{
    cJSON *root;
	cJSON *value;
    char file_name[256] = {0};

	sprintf(file_name, "%s/task_%d.json", BROADCAST_TASK_PATH, 4);
	root = parse_root_from_file(file_name);
	if(root) {
		value = cJSON_GetObjectItem(root, "filepath");
		if(value) {
			cJSON_ReplaceItemInObject(root, "filepath", cJSON_CreateString(filepath));
		} else {
			cJSON_AddStringToObject(root, "filepath", filepath);
		}

		value = cJSON_GetObjectItem(root, "url");
		if(value) {
			cJSON_DeleteItemFromObject(root, "url");
		}

	    save_root_to_file(root, file_name);
	    cJSON_Delete(root);
	}
}

static void* transferway_thread(void *arg)
{
	int ret;
	char *url = arg;

	char filename[128] = {0};
	char save_filename[128] = {0};
	char command[512] = {0};

	if(http_get_file_name(url, BROADCAST_FILE_PATH, filename))
	{
		DEBUG("transferway url error");
		goto exit_1;
	}

	//sprintf(command, "wget --timeout=300 --tries=5 %s -O %s", url, filename);
	sprintf(command, "curl -o %s --max-time 300 -k -O %s", filename, url);
	ret = myexec(command, NULL, NULL);
	if (WIFEXITED(ret) && WEXITSTATUS(ret) == 0) {
		snprintf(save_filename, sizeof(save_filename), "%s/%s", BROADCAST_FILE_PATH, TRANSFER_WAY_PICNAME);
		snprintf(command, sizeof(command), "cp %s %s -fr", filename, save_filename);
		myexec(command, NULL, NULL);

		snprintf(command, sizeof(command), "cp %s %s -fr", save_filename, "udisk/");
		myexec(command, NULL, NULL);

		update_broadcast_task_4(save_filename);

		remove(filename);

		myexec("sync", NULL, NULL);

		transferWaySetting_notify_qt();
		setting_rsp("transferWaySetting", 0);
	} else {
		setting_rsp("transferWaySetting", -1);
	}

exit_1:	
	free(arg);
	return NULL;
}

static void transferway_setting_req(CLOUD_DATA *cloud_data)
{	
	cJSON *url = NULL;
	int buf_size;

	url = cJSON_GetObjectItem(cloud_data->root, "url");
	if(url) {
		buf_size = strlen(url->valuestring) + 1;
		char *url_ptr = malloc(buf_size);
		memset(url_ptr, 0, buf_size);
		strcpy(url_ptr, url->valuestring);
		create_thread(transferway_thread, url_ptr);
	}
}

static void device_sn_config_rsp(char *chip_id)
{
	char *out;
	cJSON *root, *data, *element;

	root = cJSON_CreateObject();
	cJSON_AddStringToObject(root, "mode", "response");
	cJSON_AddStringToObject(root, "action", "device.sn_config");

	cJSON_AddItemToObject(root, "data", data = cJSON_CreateArray());
	element = cJSON_CreateObject();
	cJSON_AddStringToObject(element, "status", "success");
	cJSON_AddStringToObject(element, "message", "SN configured successfully");
	cJSON_AddStringToObject(element, "chipid", chip_id);
	cJSON_AddItemToArray(data, element);

	out = cJSON_PrintUnformatted(root);
	cJSON_Delete(root);
	gw_platform_warnbox_json_up(out, strlen(out));
	free(out);
}

static void device_sn_config(CLOUD_DATA *cloud_data)
{
	cJSON *chipid = NULL;
	cJSON *sn = NULL;

	char chipid_str[24] = {0};

	chipid = cJSON_GetObjectItem(cloud_data->data, "chipid");
	sn = cJSON_GetObjectItem(cloud_data->data, "sn");
	if(chipid && sn) {
		get_serial_number(chipid_str);
		if(strncmp(chipid->valuestring, chipid_str, 16) == 0) {
			replace_gw_devSn(sn->valuestring);
			device_sn_config_rsp(chipid_str);
			mqtt_client_reconnect();
		}
	}
}

static void natfrp_start_req(CLOUD_DATA *cloud_data)
{
	myexec("/oem/init.d/natfrp start", NULL, NULL);
	setting_rsp(cloud_data->command, 0);
}

static void natfrp_stop_req(CLOUD_DATA *cloud_data)
{
	myexec("/oem/init.d/natfrp stop", NULL, NULL);
	setting_rsp(cloud_data->command, 0);
}

static void get_relay_reboot_req(CLOUD_DATA *cloud_data)
{
	set_getrelay_opr(1);
	setting_rsp(cloud_data->command, 0);
}

static void get_relay_req(CLOUD_DATA *cloud_data)
{
	set_getrelay_opr(0);
	setting_rsp(cloud_data->command, 0);
}

static CLOUD_CMD cmd_parse_array[] = {
	{ "addDevInfo", add_modify_dev_info },
	{ "modifyDevInfo", add_modify_dev_info },
	{ "delDevInfo", del_dev_info },
	{ "clearDevInfo", clear_dev_info },
	{ "getDevInfo", get_dev_info },
	{ "heartBeat", gw_heartbeat_rsp },
	{ "setNetinfo", gw_setNetinfo_req },
	{ "setdevNodeNetinfo", gw_setdevNodeNetinfo_req },
	{ "tpunbTransparent", gw_tpunbTransparent_req },
	{ "waterLevelSetting", gw_waterLevel_req },
	{ "warnNotify", gw_warnNotify_req },
	{ "upgrade", firmware_upgrade_req },
	{ "online_scan", online_scan_req },
	{ "warn_notify", warn_notify_req },
	{ "warn_cancel", warn_cancel_req },
	{ "transferWaySetting", transferway_setting_req },
	{ "natfrp_start", natfrp_start_req },
	{ "natfrp_stop", natfrp_stop_req },
	{ "get_relay_reboot", get_relay_reboot_req },
	{ "get_relay", get_relay_req },
};

static CLOUD_CMD cmd_parse_array_null_gwid[] = {
	{ "device.sn_config", device_sn_config },
};

static void cloud_data_free(CLOUD_DATA *cloud_data)
{
	cJSON_Delete(cloud_data->root);
}

static int cloud_data_parse(char *buf, int len, CLOUD_DATA *cloud_data)
{
	cJSON *value;
	char *out;

	memset(cloud_data, 0, sizeof(CLOUD_DATA));
	cloud_data->root = cJSON_Parse(buf);
	if(cloud_data->root == NULL)
	{
		DEBUG("cJSON_Parse error %s", buf); 
		goto invalid_command;
	}

	out = cJSON_PrintUnformatted(cloud_data->root);
	DEBUG("%d,%s", len, out);
	free(out);

	value = cJSON_GetObjectItem(cloud_data->root, "gwid");
	if(value)
	{
		cloud_data->gwid = value->valuestring;
	}

	cloud_data->data = cJSON_GetObjectItem(cloud_data->root, "data");

	value = cJSON_GetObjectItem(cloud_data->root, "command");
	if(value)
	{
		cloud_data->command = value->valuestring;
	}
	else
	{
		value = cJSON_GetObjectItem(cloud_data->root, "action");
		if(value)
		{
			cloud_data->command = value->valuestring;
		}
		else
		{
			goto invalid_command;	//即没有 "command" 字段,	也没有 "action" 字段 退出处理
		}
	}

	return 0;

invalid_command:
	cloud_data_free(cloud_data);
	return -1;
}


static void cloud_data_handle(CLOUD_DATA *cloud_data)
{
	int i = 0;

	for(i=0; i<ARRAYSIZE(cmd_parse_array); i++) {
		if(strcasecmp(cmd_parse_array[i].command, cloud_data->command) == 0) {
			if(cloud_data->gwid && (strcasecmp(get_gw_sn(), cloud_data->gwid) == 0 || strcasecmp("all", cloud_data->gwid) == 0)) {
				if(cmd_parse_array[i].local_func) {
					cmd_parse_array[i].local_func(cloud_data);
				}
			}
			return;
		}
	}

	for(i=0; i<ARRAYSIZE(cmd_parse_array_null_gwid); i++) {
		if(strcasecmp(cmd_parse_array_null_gwid[i].command, cloud_data->command) == 0) {
			if(cmd_parse_array_null_gwid[i].local_func) {
				cmd_parse_array_null_gwid[i].local_func(cloud_data);
			}
			return;
		}
	}

	DEBUG("unsupported server command: %s", cloud_data->command);
}

static int handle_server_message(char *topic, void *buf, int len)
{
	CLOUD_DATA cloud_data = {0};

	if(cloud_data_parse(buf, len, &cloud_data))
	{
		return -1;
	}
	
	cloud_data_handle(&cloud_data);
	cloud_data_free(&cloud_data);
	return 0;
}

//解析平台json数据
int handle_server_data(char *topic, void *buf, int len)
{
	if(is_terminal_message(topic)) {
		hydrology_analysis(buf, DATA_TYPE_MQTT);
	} else {
		handle_server_message(topic, buf, len);
	}

	return 0;
}

